﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Fract : Form
    {
        public Fract()
        {
            InitializeComponent();
        }
        double x0;
        double y0;
        double scale;

        void f()
        {
            double v1 = this.trackBar1.Value * 0.001;
            double v2 = this.trackBar2.Value * 0.001;
            int[] arr = new int[size * size];

            double bx = -size / 2 - x0;
            double by = -size / 2 - y0;

            bool type = this.checkBox1.Checked;

            // 创建并启动4个任务
            int tcnt = 6;
            Task[] tasks = new Task[tcnt];

            for (int t = 0; t < tcnt; t++)
            {
                int start = t * (size / tcnt);
                int end = (t + 1) * (size / tcnt);


                tasks[t] = Task.Run(() =>
                {

                    for (int x = start; x < end; x++)
                    {
                        for (int y = 0; y < size; y++)
                        {
                            double cr;
                            double ci;
                            double zr;
                            double zi;
                            if (type)
                            {
                                cr = (x + bx) * scale;
                                ci = (y + by) * scale;
                                zr = v1;
                                zi = v2;
                            }
                            else
                            {
                                cr = v1;
                                ci = v2;
                                zr = (x + bx) * scale;
                                zi = (y + by) * scale;
                            }

                            int i;
                            for (i = 0; i < 256; i++)
                            {
                                if ((zr * zr + zi * zi) > 10000)
                                {
                                    break;
                                }
                                double tr = zr * zr - zi * zi;
                                double ti = zr * zi + zr * zi;

                                zr = tr + cr;
                                zi = ti + ci;
                            }
                            i = i & 255;
                            int r = i;
                            int g = i;
                            int b = i;
                            if (i == 0)
                            {
                                b = 128;
                            }
                            //bmp.SetPixel(x, y, Color.FromArgb(r, g, b));
                            arr[y * size + x] = (255 << 24) | (r << 16) | (g << 8) | b;

                        }
                    }

                });
            }

            // 等待所有任务完成
            Task.WaitAll(tasks);


            var l = bmp.LockBits(new Rectangle(0, 0, size, size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Marshal.Copy(arr, 0, l.Scan0, size * size); bmp.UnlockBits(l);

            this.pictureBox1.Image = bmp;

            //bmp.Save(idx + ".png");
            //return bmp;
        }
        int size;
        Bitmap bmp;

        private void Fract_Load(object sender, EventArgs e)
        {

            size = 512;

            x0 = 0;
            y0 = 0;
            scale = 1.0 / size * 5.0;

            bmp = new Bitmap(size, size);

            f();

            this.pictureBox1.MouseDown += pictureBox1_MouseDown;
            this.pictureBox1.MouseUp += pictureBox1_MouseUp;
            this.pictureBox1.MouseWheel += pictureBox1_MouseWheel;
        }

        int basex;
        int basey;
        void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            x0 -= basex - e.X;
            y0 -= basey - e.Y;
            f();
        }
        void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            basex = e.X;
            basey = e.Y;
        }

        void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
            {
                scale = scale / 1.1;
                x0 = x0 * 1.1;
                y0 = y0 * 1.1;
            }
            else
            {
                scale = scale * 1.1;
                x0 = x0 / 1.1;
                y0 = y0 / 1.1;
            }
            f();
        }


        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            f();
        }

        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            f();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            f();
        }

    }
}